#include "networksd.h"

#include "../core/core.h"

#include <QTabWidget>
#include <QWidget>
#include <QGroupBox>
#include <QSpinBox>
#include <QLineEdit>
#include <QCheckBox>
#include <QLabel>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QFormLayout>
#include <QPushButton>
#include <QMessageBox>
#include <QApplication>
#include <QCryptographicHash>
#include <QDebug>

#include "../ui/openlineedit.h"
#include "../ui/newuserdialog.h"
#include "../ui/changepassword.h"


class NetworkSD::NetworkSDPrivate {
public:
	NetworkSDPrivate();
	~NetworkSDPrivate();

	QTabWidget *m_pTab;

	QSpinBox *m_pListeningPort;
	QLineEdit *m_pServerAddress;
	QCheckBox *m_pSslErrors;
	QCheckBox *m_pAutoConnect;
	QCheckBox *m_pErrorsConnect;

	QLineEdit *m_pUserName;
	QLineEdit *m_pPassword;


	bool m_spinboxChanged;
	bool m_checkboxChanged;
	bool m_connectChanged;
	bool m_errorsChange;
};

NetworkSD::NetworkSDPrivate::NetworkSDPrivate(){
	m_pTab = NULL;

	m_spinboxChanged = false;
	m_checkboxChanged = false;
	m_connectChanged = false;
	m_errorsChange = false;
}

NetworkSD::NetworkSDPrivate::~NetworkSDPrivate(){
	delete m_pTab;
}

//end of d-class part
//------------------------------------------------------------------------------
NetworkSD::NetworkSD() :
	QObject(0),
	d(new NetworkSDPrivate())
{
}

NetworkSD::~NetworkSD(){
	delete d;
}

QString NetworkSD::category() const {
	return tr("Sieć");
}

QIcon NetworkSD::categoryIcon() const {
	return QIcon(":/settings/res/preferences-system-network.png");
}

QTabWidget* NetworkSD::createPages(){
	if( d->m_pTab )
		return d->m_pTab;



	d->m_pTab = new QTabWidget();

	QWidget *general = new QWidget( d->m_pTab );
	d->m_pTab->addTab( general, tr("Ogólne") );



	QGroupBox *box = new QGroupBox( tr("Serwer"), general );
	QFormLayout *formBox = new QFormLayout( box );


	d->m_pServerAddress = new QLineEdit( box );
	d->m_pServerAddress->setText(
			Core::instance()->settings()->value( Setting::serverAddrKey,
												 Setting::serverAddrDef )
			.toString() );
	d->m_pServerAddress->setToolTip( tr("Domyślny adres: %1")
									 .arg(Setting::serverAddrDef.toString()) );


	d->m_pListeningPort = new QSpinBox( box );
	d->m_pListeningPort->setRange(0, 65535);
	d->m_pListeningPort->setValue(
			Core::instance()->settings()->value( Setting::serverPortKey,
												 Setting::serverPortDef )
			.toInt() );
	d->m_pListeningPort->setToolTip( tr("Domyślny port: %1")
									 .arg(
							  QString::number( Setting::serverPortDef.toInt() ))
									 );
	connect( d->m_pListeningPort, SIGNAL(valueChanged(int)),
			 this, SLOT(spinboxChanged(int)) );

	d->m_pSslErrors = new QCheckBox( box );
	d->m_pSslErrors->setText( tr("Obecne") );
	d->m_pSslErrors->setChecked(
			Core::instance()->settings()
									->value( Setting::sslErrorsIgnoreKey,
											 Setting::sslErrorsIgnoreDef )
									.toBool() );

	d->m_pSslErrors->setToolTip( tr("Określa czy błędy SSL mają być ignorowane"
								   "\nW przypadku gdy serwer posiada certyfikat"
								   " z podpisem własnym, to pole musi być "
								   "zaznaczone") );
	connect( d->m_pSslErrors, SIGNAL(stateChanged(int)),
			 this, SLOT(checkboxChanged(int)) );


	d->m_pAutoConnect = new QCheckBox( box );
	d->m_pAutoConnect->setText( tr("Obecne") );
	d->m_pAutoConnect->setChecked(
			Core::instance()->settings()
									->value( Setting::autoConnectKey,
											 Setting::autoConnectDef )
									.toBool() );

	d->m_pAutoConnect->setToolTip( tr("Określa czy program ma się automatycznie"
								   "łączyć po uruchmieniu aplikacji") );
	connect( d->m_pAutoConnect, SIGNAL(stateChanged(int)),
			 this, SLOT(checkboxChanged(int)) );


	d->m_pErrorsConnect = new QCheckBox( box );
	d->m_pErrorsConnect->setText( tr("Obecne") );
	d->m_pErrorsConnect->setChecked(
			Core::instance()->settings()
									->value( Setting::errorsConnectKey,
											 Setting::errorsConnectDef )
									.toBool() );

	d->m_pErrorsConnect->setToolTip( tr("Określa czy program ma się pokazywać "
									 "błędy połączenia w postaci wyskakujących"
									 " okienek") );
	connect( d->m_pErrorsConnect, SIGNAL(stateChanged(int)),
			 this, SLOT(errorsChange(int)) );


	formBox->addRow( tr("Adres:"), d->m_pServerAddress );
	formBox->addRow( tr("Port:"), d->m_pListeningPort );
	formBox->addRow( tr("Ignoruj błędy SSL:"), d->m_pSslErrors );
	formBox->addRow( tr("Łącz przy uruchamianiu:"), d->m_pAutoConnect );
	formBox->addRow( tr("Pokazuj błędy połączenia:"), d->m_pErrorsConnect );

	box->setLayout( formBox );

	//Użytkownik
	//----------
	QGroupBox *box2 = new QGroupBox( tr("Użytkownik"), general );
	QGridLayout *box2main = new QGridLayout( box2 );
	QWidget *box2form = new QWidget( box2 );

	QFormLayout *box2formLayout = new QFormLayout( box2form );

	d->m_pUserName = new QLineEdit( box2form );

	d->m_pUserName->setText(
			Core::instance()->settings()->value( Setting::userNameKey,
												 Setting::userNameDef )
			.toString() );

	d->m_pPassword = new QLineEdit( box2form );
	d->m_pPassword->setEchoMode( QLineEdit::Password );

	if( Core::instance()->settings()->value( Setting::passwordKey,
											 Setting::passwordDef ).isValid() )
	{
		d->m_pPassword->setText( tr("no, you do not see the password") );
	}else{
		d->m_pPassword->setText("");
	}



	d->m_pPassword->setToolTip( tr("Ilość ilość symboli zastępczych jest inna "
								   "od długości twojego hasła?\nNie przejmuj "
								   "się, to dodatkowe zabezpieczenie") );

	box2formLayout->addRow( tr("Login:"), d->m_pUserName );
	box2formLayout->addRow( tr("Hasło:"), d->m_pPassword );


	box2form->setLayout( box2formLayout );
	box2main->addWidget( box2form );


	QWidget *box2buttons = new QWidget( box2 );

	QHBoxLayout *box2buttonsLayout = new QHBoxLayout( box2buttons );

	QPushButton *button1 = new QPushButton(tr("Nowy użytkownik"), box2buttons);
	QPushButton *button2 = new QPushButton(tr("Zmień hasło"), box2buttons);

	connect( button1, SIGNAL(clicked()), this, SLOT(addNewUser()) );
	connect( button2, SIGNAL(clicked()), this, SLOT(changePassword()) );

	box2buttonsLayout->addWidget( button1 );
	box2buttonsLayout->addWidget( button2 );


	box2buttons->setLayout( box2buttonsLayout );
	box2main->addWidget( box2buttons );

	box2->setLayout( box2main );


	general->setLayout( new QVBoxLayout( general ) );

	general->layout()->addWidget( box );
	general->layout()->addWidget( box2 );

	return d->m_pTab;
}

void NetworkSD::spinboxChanged(int){
	d->m_spinboxChanged = true;
}

void NetworkSD::checkboxChanged(int){
	d->m_checkboxChanged = true;
}

void NetworkSD::autoconnectChange(int){
	d->m_connectChanged = true;
}

void NetworkSD::errorsChange(int){
	d->m_errorsChange = true;
}

void NetworkSD::save(){
	if( d->m_spinboxChanged ){
		Core::instance()->settings()->setValue( Setting::serverPortKey,
												d->m_pListeningPort->value() );
		d->m_spinboxChanged = false;
	}

	if( d->m_pServerAddress->isModified() ){
		Core::instance()->settings()->setValue( Setting::serverAddrKey,
												d->m_pServerAddress->text() );
		d->m_pServerAddress->setModified( false );
	}

	if( d->m_checkboxChanged ){
		Core::instance()->settings()
								->setValue( Setting::sslErrorsIgnoreKey,
											d->m_pSslErrors->isChecked() );
		d->m_checkboxChanged = false ;
	}

	if( d->m_connectChanged ){
		Core::instance()->settings()
								->setValue( Setting::autoConnectKey,
											d->m_pAutoConnect->isChecked() );
		d->m_connectChanged = false ;
	}

	if( d->m_errorsChange ){
		Core::instance()->settings()
								->setValue( Setting::errorsConnectKey,
											d->m_pErrorsConnect->isChecked() );
		d->m_errorsChange = false ;
	}

	if( d->m_pUserName->isModified() ){
		Core::instance()->settings()->setValue(	Setting::userNameKey,
												d->m_pUserName->text() );

		d->m_pUserName->setModified( false );
	}

	if( d->m_pPassword->isModified() ){
		QByteArray sha1 = QCryptographicHash::hash(
				d->m_pPassword->text().toUtf8(), QCryptographicHash::Sha1 );

		Core::instance()->settings()->setValue(	Setting::passwordKey,
												QString(sha1.toHex()) );
		if( !d->m_pPassword->text().isEmpty() )
			d->m_pPassword->setText( tr("no, you do not see the password") );

		d->m_pPassword->setModified( false );
	}
}

void NetworkSD::reset(){
	if( d->m_spinboxChanged ){
		d->m_pListeningPort->setValue(
				Core::instance()->settings()->value(
						Setting::serverPortKey,
						Setting::serverPortDef ).toInt() );

		d->m_spinboxChanged = false;
	}

	if( d->m_pServerAddress->isModified() ){
		d->m_pServerAddress->setText(
				Core::instance()->settings()->value(
						Setting::serverAddrKey,
						Setting::serverAddrDef ).toString() );

		d->m_pServerAddress->setModified( false );
	}

	if( d->m_checkboxChanged ){
		d->m_pSslErrors->setChecked(
				Core::instance()->settings()
									->value( Setting::sslErrorsIgnoreKey,
											 Setting::sslErrorsIgnoreDef )
									.toBool() );
		d->m_checkboxChanged = false ;
	}

	if( d->m_connectChanged ){
		d->m_pAutoConnect->setChecked(
				Core::instance()->settings()
									->value( Setting::autoConnectKey,
											 Setting::autoConnectDef )
									.toBool() );
		d->m_connectChanged = false ;
	}

	if( d->m_errorsChange ){
		d->m_pAutoConnect->setChecked(
				Core::instance()->settings()
									->value( Setting::errorsConnectKey,
											 Setting::errorsConnectDef )
									.toBool() );
		d->m_errorsChange = false ;
	}

	if( d->m_pUserName->isModified() ){
		d->m_pUserName->setText(
				Core::instance()->settings()->value(
						Setting::userNameKey,
						Setting::userNameDef ).toString() );

		d->m_pUserName->setModified( false );
	}

	if( d->m_pPassword->isModified() ){
		if( Core::instance()->settings()->value( Setting::passwordKey,
												 Setting::passwordDef )
			.isValid() )
		{
			d->m_pPassword->setText( tr("no, you do not see the password") );
		}else{
			d->m_pPassword->setText("");
		}

		d->m_pPassword->setModified( false );
	}
}

void NetworkSD::addNewUser(){
	NewUserDialog *dialog = new NewUserDialog();

	connect(dialog, SIGNAL(accepted()), dialog, SLOT(deleteLater()));
	connect(dialog, SIGNAL(rejected()), dialog, SLOT(deleteLater()));
	connect(qApp, SIGNAL(aboutToQuit()), dialog, SLOT(deleteLater()));

	dialog->show();
}

void NetworkSD::changePassword(){
	ChangePassword *dialog = new ChangePassword();

	connect(dialog, SIGNAL(accepted()), dialog, SLOT(deleteLater()));
	connect(dialog, SIGNAL(rejected()), dialog, SLOT(deleteLater()));
	connect(qApp, SIGNAL(aboutToQuit()), dialog, SLOT(deleteLater()));

	dialog->show();
}

